package com.smile.frame.seckill.core.disruptor;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.lmax.disruptor.BlockingWaitStrategy;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;

import javax.annotation.Resource;
import java.util.concurrent.ThreadFactory;

/**
 * @author LGC
 */
@Slf4j
@Configuration
public class DisruptorConfig {

    @Resource
    private SecondKillEventConsumer secondKillEventConsumer;

    /**
     * RingBuffer 负责对通过 Disruptor 进行交换的数据（事件）进行存储和更新
     *
     * @return
     */
    @Bean(value = "secondKillEventRingBuffer")
    public RingBuffer<SecondKillEvent> secondKillEventRingBuffer() {
        // 指定ringBuffer字节大小，必须为2的N次方（能将求模运算转为位运算提高效率），否则将影响效率
        int ringBufferSize = 1024 * 256;
        // 设置线程名称
//        ThreadFactory guavaThreadFactory = new ThreadFactoryBuilder().setNameFormat("disruptor-%s").build();
        ThreadFactory springThreadFactory = new CustomizableThreadFactory("disruptor-");
        // 事件工厂
        SecondKillEventFactory factory = new SecondKillEventFactory();
        // 单线程模式，获取额外的性能
        Disruptor<SecondKillEvent> disruptor = new Disruptor<>(factory, ringBufferSize, springThreadFactory,
                ProducerType.SINGLE, new BlockingWaitStrategy());
        // 设置事件业务处理器---消费者，可以有多个
        disruptor.handleEventsWith(secondKillEventConsumer);
        // 启动disruptor线程
        disruptor.start();
        log.info("disruptor线程 启动成功");
        return disruptor.getRingBuffer();
    }
}